<script setup lang="ts">
import * as echarts from 'echarts';
import chinaMap from './china.json?raw';
import type { Defect, YLabelType } from '@/index.d';
import { getUniqueKeysFromObjectArray } from '@/tool';
import { useWindowSize } from '@vueuse/core';
const { width, height } = useWindowSize();
const leave = ref(true);
const props = defineProps({
  defectList: Array<Defect>,
  yLabelType: {
    validator(value: YLabelType) {
      return ['缺陷数量', '缺陷长度', '工件数量'].includes(value);
    }
  },
  checkAll: {
    type: Boolean,
    default: false
  }
});

interface MapData {
  name: string;
  value: number;
}

interface MapDataList {
  data: Array<MapData>;
  min: number;
  max: number;
}

const mapDataListWithMinAndMax: MapDataList = {
  data: [],
  min: 0,
  max: 0
};

const generateMapDataList = () => {
  const addressList: Array<string> = getUniqueKeysFromObjectArray(props.defectList!, 'province');
  const mapDataList: Array<MapData> = [];
  const mapObj: { [key: string]: number } = {};
  addressList.forEach(address => (mapObj[address] = 0));

  if (props.yLabelType === '缺陷数量') {
    props.defectList?.forEach(element => {
      mapObj[element.province!] += 1;
    });
  } else if (props.yLabelType === '缺陷长度') {
    props.defectList?.forEach(element => {
      mapObj[element.province!] += element.defectSize as number;
    });
  }

  Object.keys(mapObj).forEach(key => {
    mapDataList.push({
      name: key,
      value: mapObj[key]
    });
  });
  ((mapDataListWithMinAndMax.data = mapDataList),
    (mapDataListWithMinAndMax.min = Math.min(...mapDataList.map(item => item.value))),
    (mapDataListWithMinAndMax.max = Math.max(...mapDataList.map(item => item.value))));
};

let echartContainer: HTMLDivElement;
let chartInstance: echarts.ECharts;
let mapOption: echarts.EChartsOption;

const makeOption = () => {
  generateMapDataList();
  mapOption = {
    title: {
      text: (props.checkAll ? '全部月份' : '近6个月') + props.yLabelType!,
      textStyle: {
        fontSize: 14
      }
    },
    toolbox: {
      feature: {
        saveAsImage: {}
      }
    },
    visualMap: {
      left: 'right',
      min: mapDataListWithMinAndMax.min,
      max: mapDataListWithMinAndMax.max,
      inRange: {
        color: [
          '#313695',
          '#4575b4',
          '#74add1',
          '#abd9e9',
          '#e0f3f8',
          '#ffffbf',
          '#fee090',
          '#fdae61',
          '#f46d43',
          '#d73027',
          '#a50026'
        ]
      },
      text: ['高', '低'],
      calculable: true
    },
    series: [
      {
        id: 'population',
        type: 'map',
        roam: true,
        map: 'CHINA',
        animationDurationUpdate: 1000,
        universalTransition: true,
        data: mapDataListWithMinAndMax.data
      }
    ]
  };
};

const makeChart = () => {
  if (
    props.defectList === undefined ||
    props.defectList.length === 0 ||
    props.yLabelType === undefined
  ) {
    return;
  }
  leave.value = false;
  makeOption();
  chartInstance && echarts.dispose(echartContainer);
  chartInstance = echarts.init(echartContainer);
  echarts.registerMap('CHINA', chinaMap);
  chartInstance.setOption(mapOption);
};

onMounted(() => {
  echartContainer = document.querySelector('#mapContainer') as HTMLDivElement;
  leave.value = false;
});

watch(
  () => [width.value, height.value],
  () => {
    chartInstance && chartInstance.resize();
  }
);

watch(
  () => [props, leave],
  () => {
    makeChart();
  },
  {
    deep: true
  }
);

onUnmounted(() => {
  chartInstance && echarts.dispose(chartInstance);
  leave.value = true;
});
</script>
<template>
  <div id="mapContainer"></div>
</template>
<style scoped lang="scss">
#mapContainer {
  width: 100%;
  height: 100%;
}
</style>
